package com.springboot.interceptor;

import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;

import com.springboot.common.ResponseCode;
import com.springboot.common.Result;
import com.springboot.entity.Users;
import com.springboot.exception.CustomException;
import com.springboot.service.IUsersService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import jakarta.annotation.Resource;

/**
 * jwt登录拦截器
 */
@Component
public class JwtInterceptor implements HandlerInterceptor {
    private static final Logger log = LoggerFactory.getLogger(JwtInterceptor.class);

    @Resource
    private IUsersService usersService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {

        String uri = request.getRequestURI();
        if (uri.startsWith("/api/files/")) {
            log.info("放行图片请求");
            return true;
        }

        if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
            log.info("放行Options");
            return true;
        }
        //1.获取token
        String authHeader = request.getHeader("Authorization");

        // 2. 第一步校验：Authorization 头是否存在
        if (authHeader == null || authHeader.trim().isEmpty()) {
            throw new CustomException(ResponseCode.UNAUTHORIZED.getCode(),"请先登录（请求头缺少 Authorization 令牌）");
        }

        // 3. 第二步校验：是否以 "Bearer " 开头（注意空格，必须严格匹配）
        if (!authHeader.startsWith("Bearer ")) {
            throw new CustomException("令牌格式错误！正确格式为：Authorization: Bearer <your_token>");
        }

        // 4. 提取纯令牌（去除 "Bearer " 前缀，长度为7，因为 "Bearer " 包含空格共7个字符）
        String token = authHeader.substring(7).trim(); // substring(7) 截取第7个字符后的内容
        if (StrUtil.isBlank(token)) {
            token = request.getParameter("token");
        }
        if (token == null || token.trim().isEmpty()) {
            Result.error("wu");
            throw new CustomException("错误：请求头中未携带令牌");

        }
        //2.认证
        if (StrUtil.isBlank(token)) {
            throw new CustomException("无token，重新登录");
        }
        try {
            // 验证token是否过期
            JWT.decode(token).getExpiresAt();

            //获取token中的id
            String id = JWT.decode(token).getAudience().get(0);

            // 尝试作为用户验证
            Users users = usersService.getById(Integer.parseInt(id));
            if (users != null) {
                // 验证token签名
                JWTVerifier verifier = JWT.require(Algorithm.HMAC256(users.getPassword())).build();
                verifier.verify(token);
                return true;
            }

            throw new CustomException("用户不存在");
        } catch (TokenExpiredException e) {
            log.error("token已过期", e);
            throw new CustomException("token已过期，请重新登录");
        } catch (IndexOutOfBoundsException e) {
            String errMsg = "token中未包含有效的ID";
            log.error(errMsg + ",token=" + token, e);
            throw new CustomException(errMsg);
        } catch (NumberFormatException e) {
            String errMsg = "token中的ID不是有效的整数";
            log.error(errMsg + ",token=" + token, e);
            throw new CustomException(errMsg);
        } catch (Exception e) {
            String errMsg = "token验证失败";
            log.error(errMsg + ",token=" + token, e);
            throw new CustomException(errMsg);
        }
    }
}